为了账号安全,请及时绑定邮箱和手机立即绑定

java并发之同步辅助类CyclicBarrier

标签:
Java

CyclicBarrier含义:

栅栏允许两个或者多个线程在某个集合点同步。当一个线程到达集合点时,它将调用await()方法等待其它的线程。线程调用await()方法后,CyclicBarrier将阻塞这个线程并将它置入休眠状态等待其它线程的到来。等最后一个线程调用await()方法时,CyclicBarrier将唤醒所有等待的线程然后这些线程将继续执行。CyclicBarrier可以传入另一个Runnable对象作为初始化参数。当所有的线程都到达集合点后,CyclicBarrier类将Runnable对象作为线程执行。

方法:
await():使线程置入休眠直到最后一个线程的到来之后唤醒所有休眠的线程

例子
在矩阵(二维数组)中查找一个指定的数字。矩阵将被分为多个子集,每个子集交给一个线程去查找。当所有线程查找完毕后交给最后的线程汇总结果。
查找类:在一个子集中查找指定数字,找到之后把结果存储后调用await()方法置入休眠等待最后一个线程的到来唤醒

import java.util.List;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;public class Searcher implements Runnable {private  CyclicBarrier barrier;private  int[] submock;private  List<Result> result;private int row;private int searchNmu;public Searcher(int[] submock, List<Result> result,  CyclicBarrier barrier, int row, int searchNmu) {    this.barrier = barrier;    this.submock = submock;    this.result = result;    this.row = row;    this.searchNmu = searchNmu;}@Overridepublic void run() {    System.out.printf("%s: Processing lines from %d .\n", Thread.currentThread().getName(), row);    for(int i=0; i<submock.length; i++){        if(submock[i] == searchNmu){            Result r = new Result();            r.setRow(row);            r.setCol(i);            result.add(r);        }    }    System.out.printf("%s: Lines processed.\n", Thread.currentThread().getName());    try {        barrier.await();    } catch (InterruptedException e) {        e.printStackTrace();    } catch (BrokenBarrierException e) {        e.printStackTrace();    }}}

结果类:

public class Result {//行int row;//列int col;public int getRow() {    return row;}public void setRow(int row) {    this.row = row;}public int getCol() {    return col;}public void setCol(int col) {    this.col = col;}

}

汇总类:汇总每个Searcher找到的结果:
import java.util.List;

public class Grouper implements Runnable {

private List<Result> result;int[][] mock;public Grouper(List<Result> result, int[][] mock) {    this.result = result;    this.mock = mock;}@Overridepublic void run() {    System.out.printf("Grouper: Processing results...\n");    for (int i = 0; i < result.size(); i++) {        Result r = result.get(i);        if(r!=null)        System.out.println("mock[" + r.row + "][" + r.col + "]" + mock[r.row][r.col]);    }    System.out.printf("Grouper proccessing end...\n");}}

主函数,如何把Searcher和Grouper类配合起来呢??

import java.util.ArrayList;import java.util.List;import java.util.concurrent.CyclicBarrier;public class CyclicBarrierMain {    public static void main(String[] args) {    // 要找的数据    final int SEARCH = 5;    // 矩阵的声明    int[][] mock = { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },            { 1, 2, 3, 5, 5, 6, 7, 8, 9, 10 },            { 5, 2, 3, 4, 5, 6, 7, 8, 9, 10 },             { 1, 2, 3, 4, 6, 6, 7, 8, 5, 10 },             { 1, 5, 3, 4, 5, 6, 7, 8, 5, 10 },            { 1, 5, 3, 4, 12, 6, 7, 8, 0, 5 } };    // 查找的线程数    int PARTICIPANTS = mock.length;    List<Result> result = new ArrayList<Result>();    // 汇总线程    Grouper grouper = new Grouper(result, mock);    // 栅栏,传入参数含义:线程同步个数,汇总线程    CyclicBarrier barrier = new CyclicBarrier(PARTICIPANTS, grouper);    Searcher searchers[] = new Searcher[PARTICIPANTS];    for (int i = 0; i < PARTICIPANTS; i++) {        searchers[i] = new Searcher(mock[i], result, barrier, i, SEARCH);        Thread thread = new Thread(searchers[i]);        thread.start();    }    System.out.printf("Main: The main thread has finished.\n");}

}

需要注意的地方
线程完成任务后调用CyclicBarrier的await()方法休眠等待。在所有线程在集合点均到达时,栅栏调用传入的Runnable对象进行最后的执行。
与CountDownLatch的区别:
在所有线程到达集合点后接受一个Runnable类型的对象作为后续的执行
没有显示调用CountDown()方法
CountDownLatch一般只能使用一次,CyclicBarrier可以多次使用
应用场景
多个线程做任务,等到达集合点同步后交给后面的线程做汇总


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消